package com.ruoyi.system.service.impl;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Map;

import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.core.domain.model.LoginUser;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.system.domain.PropertyPicture;
import com.ruoyi.system.enums.ExcelFieldEnum;
import com.ruoyi.system.kiteUtils.CommUtils;
import com.ruoyi.system.mapper.PropertyPictureMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.system.mapper.PropertyJiajuMapper;
import com.ruoyi.system.mapper.PropertyChangeMapper;
import com.ruoyi.system.domain.PropertyJiaju;
import com.ruoyi.system.domain.PropertyChange;
import com.ruoyi.system.service.IPropertyJiajuService;
import org.springframework.web.multipart.MultipartFile;

@Service
public class PropertyJiajuServiceImpl implements IPropertyJiajuService {
    @Autowired
    private PropertyJiajuMapper propertyJiajuMapper;

    @Autowired
    private PropertyChangeMapper propertyChangeMapper;

    @Autowired
    private PropertyPictureMapper propertyPictureMapper;

    @Override
    public PropertyJiaju selectPropertyJiajuById(Long id) {
        return propertyJiajuMapper.selectPropertyJiajuById(id);
    }

    @Override
    public List<PropertyJiaju> selectPropertyJiajuList(PropertyJiaju propertyJiaju) {
        List<PropertyJiaju> list = propertyJiajuMapper.selectPropertyJiajuList(propertyJiaju);
        for (PropertyJiaju item:list){
            PropertyPicture propertyPicture = propertyPictureMapper.selectByNameAndType(item.getFurnitureName(), "3");
            if(propertyPicture !=null){
                item.setPictureUrl(propertyPicture.getPictureUrl());
            }
            item.setChangeSize(propertyChangeMapper.selectCountByNumberAndType(item.getFurnitureNumber(), "家具资产"));

        }
        return list;
    }


    @Override
    @Transactional
    public int insertPropertyJiaju(PropertyJiaju propertyJiaju) {
        // 检查家具编号唯一性
        PropertyJiaju existing = propertyJiajuMapper.selectByFurnitureNumber(propertyJiaju.getFurnitureNumber());
        if (existing != null) {
            throw new ServiceException("家具编号 " + propertyJiaju.getFurnitureNumber() + " 已存在");
        }
        //校验数据
        checkPropertyJiaju(propertyJiaju);
        // 设置创建信息
        propertyJiaju.setCreateBy(SecurityUtils.getUsername());
        propertyJiaju.setCreateTime(new Date());
        int result = propertyJiajuMapper.insertPropertyJiaju(propertyJiaju);
        if (result <= 0) {
            return result;
        }
        // 3. 记录变更日志
        addPropertyChange4Insert(propertyJiaju, "新增");
        return result;
    }

    @Override
    @Transactional
    public int updatePropertyJiaju(PropertyJiaju propertyJiaju) {
        // 1. 查询原始数据
        PropertyJiaju originalJiaju = propertyJiajuMapper.selectPropertyJiajuById(propertyJiaju.getId());
        // 2. 执行更新操作
        propertyJiaju.setUpdateBy(SecurityUtils.getUsername());
        propertyJiaju.setUpdateTime(new Date());
        int result = propertyJiajuMapper.updatePropertyJiaju(propertyJiaju);
        // 3.添加变更流水
        addPropertyChange4Update(originalJiaju, propertyJiaju, "家具资产修改");

        return result;
    }

    @Override
    public int deletePropertyJiajuByIds(Long[] ids) {
        return propertyJiajuMapper.deletePropertyJiajuByIds(ids);
    }

    @Override
    public int deletePropertyJiajuById(Long id) {
        // 删除前记录变更日志
        PropertyJiaju propertyJiaju = propertyJiajuMapper.selectPropertyJiajuById(id);
//        if (propertyJiaju != null) {
//            recordPropertyChange(propertyJiaju, "删除", null);
//        }
        return propertyJiajuMapper.deletePropertyJiajuById(id);
    }

    @Override
    @Transactional
    public void importData(MultipartFile file) {
        List<PropertyJiaju> list;
        ExcelUtil<PropertyJiaju> excelUtil = new ExcelUtil<>(PropertyJiaju.class);
        try {
            list = excelUtil.importExcel(file.getInputStream());
        } catch (Exception e) {
            throw new ServiceException("文件读取失败,请检查文件格式是否正确！");
        }

        StringBuilder errMsg = new StringBuilder();
        for (int i = 0; i < list.size(); i++) {
            PropertyJiaju item = list.get(i);
            try {
                PropertyJiaju existing = propertyJiajuMapper.selectByFurnitureNumber(item.getFurnitureNumber());
                if (existing != null) {
                    throw new ServiceException("家具编号 " + item.getFurnitureNumber() + " 已存在");
                }
                checkPropertyJiaju(item);
                item.setCreateBy(SecurityUtils.getUsername());
                item.setCreateTime(new Date());
                //永远插入登入人的工号姓名作为变更人信息
                SysUser user = getLoginSysUser();
                item.setRevisedPeople(user.getUserName());//工号
                item.setBackupFields9(user.getNickName());//姓名
                propertyJiajuMapper.insertPropertyJiaju(item);
                addPropertyChange4Insert(item, "批量新增");
            } catch (ServiceException e) {
                errMsg.append("第").append(i + 2).append("行错误，").append(e.getMessage()).append("</br>");
            }
        }
        if (StringUtils.isNotBlank(errMsg)) {
            throw new ServiceException(errMsg.toString());
        }
    }

    @Override
    @Transactional
    public void batchEdit(MultipartFile file) {
        List<PropertyJiaju> list;
        ExcelUtil<PropertyJiaju> excelUtil = new ExcelUtil<>(PropertyJiaju.class);
        try {
            list = excelUtil.importExcel(file.getInputStream());
        } catch (Exception e) {
            throw new ServiceException("文件读取失败,请检查文件格式是否正确！");
        }

        StringBuilder errMsg = new StringBuilder();
        for (int i = 0; i < list.size(); i++) {
            PropertyJiaju item = list.get(i);
            try {
                checkPropertyJiaju(item);
                // 1. 查询原始数据
                PropertyJiaju originalJiaju = propertyJiajuMapper.selectByFurnitureNumber(item.getFurnitureNumber());
                if(originalJiaju ==null){
                    throw new ServiceException("根据家具编号，系统未找到该家具资产");
                }
                item.setId(originalJiaju.getId());
                // 2. 执行更新操作
                //永远插入登入人的工号姓名作为变更人信息
                SysUser user = getLoginSysUser();
                item.setRevisedPeople(user.getUserName());//工号
                item.setBackupFields9(user.getNickName());//姓名

                propertyJiajuMapper.updatePropertyJiaju(item);
                // 3.添加变更流水
                addPropertyChange4Update(originalJiaju, item, "批量修改");
            } catch (ServiceException e) {
                errMsg.append("第").append(i + 2).append("行错误，").append(e.getMessage()).append("</br>");
            }
        }
        if (StringUtils.isNotBlank(errMsg)) {
            throw new ServiceException(errMsg.toString());
        }
    }


    private void checkPropertyJiaju(PropertyJiaju obj) {
        if (StringUtils.isBlank(obj.getFurnitureNumber())) {
            throw new ServiceException("【家具编号】不能为空");
        }
        if (StringUtils.isBlank(obj.getFurnitureName())) {
            throw new ServiceException("【家具名称】不能为空");
        }
        if (StringUtils.isBlank(obj.getInstrumentNewNumber())) {
            throw new ServiceException("【资产新编号】不能为空");
        }
        if (StringUtils.isBlank(obj.getStorageLocation())) {
            throw new ServiceException("【存放地】不能为空");
        }
        if (StringUtils.isBlank(obj.getRevisedReason())) {
            throw new ServiceException("【最新修订事由】不能为空");
        }
//        try {
//            CommUtils.findUserCode(obj.getRevisedPeople());
//        } catch (ServiceException e) {
//            throw new ServiceException("【最新修订人】的user_code未找到，请重新检查或联系管理员");
//        }
        try {
            CommUtils.findUserCode(obj.getUsers());
        } catch (ServiceException e) {
            throw new ServiceException("【使用人】的user_code未找到，请重新检查或联系管理员");
        }
        try {
            CommUtils.findUserCode(obj.getKeeper());
        } catch (ServiceException e) {
            throw new ServiceException("【保管人】的user_code未找到，请重新检查或联系管理员");
        }
        try {
            CommUtils.findUserCode(obj.getResponser());
        } catch (ServiceException e) {
            throw new ServiceException("【责任人】的user_code未找到，请重新检查或联系管理员");
        }
//        try {
//            CommUtils.findUserCode(obj.getResponserHistory());
//        } catch (ServiceException e) {
//            throw new ServiceException("【历史责任人】的user_code未找到，请重新检查或联系管理员");
//        }
    }

    private void addPropertyChange4Insert(PropertyJiaju propertyJiaju, String type) {
        PropertyChange changeLog = new PropertyChange();
        changeLog.setInstrumentNumber(propertyJiaju.getFurnitureNumber()); //编号
        changeLog.setBackupFields1(propertyJiaju.getFurnitureName());//名称
        // 变更情况改为动态生成
        StringBuilder changeDetail = new StringBuilder("【新增家具资产】");
        List<Map<ExcelFieldEnum, String>> excelFields = CommUtils.getExcelFields(propertyJiaju);
        for (Map<ExcelFieldEnum, String> map : excelFields) {
            String value = map.get(ExcelFieldEnum.FILED_VALUE);
            String excelAnnotationName = map.get(ExcelFieldEnum.EXCEL_ANNOTATION_NAME);
            if (StringUtils.isNotBlank(value)) {
                changeDetail.append(excelAnnotationName).append("：").append(value).append("；");
            }
        }
        changeLog.setChangeSituationStatus(changeDetail.toString()); //变更情况
        // 操作人信息
        String revisedPeople = propertyJiaju.getRevisedPeople();
        revisedPeople = StringUtils.isNotBlank(revisedPeople) ? revisedPeople : SecurityUtils.getUsername();
        changeLog.setChangeSituationPerson(revisedPeople);//变更人
        // 时间信息
        String revisedTm = propertyJiaju.getRevisedTm();
        revisedTm = StringUtils.isNotBlank(revisedTm) ? revisedTm : new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date());
        changeLog.setChangeSituationTm(revisedTm); //变更时间
        // 变更事由
        String revisedReason = propertyJiaju.getRevisedReason();
        changeLog.setChangeSituationResason(StringUtils.isNotBlank(revisedReason) ? revisedReason : "初始入库"); //变更事由
        // 操作类型标记
        changeLog.setBackupFields2("新增"); //变更类型
        changeLog.setBackupFields3("家具资产");
        changeLog.setBackupFields4(propertyJiaju.getStorageLocation());//存放地
        changeLog.setBackupFields5(propertyJiaju.getKeeper());//保管人
        changeLog.setBackupFields6(propertyJiaju.getUsers());//使用人
        changeLog.setBackupFields7(propertyJiaju.getResponser());//责任人
        changeLog.setBackupFields8(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
        changeLog.setBackupFields9(propertyJiaju.getBackupFields9());
        propertyChangeMapper.insertPropertyChange(changeLog);
    }

    private void addPropertyChange4Update(PropertyJiaju originalJiaju, PropertyJiaju newJiaju, String updateType) {
        PropertyChange changeLog = new PropertyChange();
        changeLog.setInstrumentNumber(newJiaju.getFurnitureNumber()); //编号
        changeLog.setBackupFields1(newJiaju.getFurnitureName());//名称
        StringBuilder changeDetail = new StringBuilder("【修改家具资产】，");
        List<Map<ExcelFieldEnum, String>> oldExcelFields = CommUtils.getExcelFields(originalJiaju);
        List<Map<ExcelFieldEnum, String>> newExcelFields = CommUtils.getExcelFields(newJiaju);
        int changeSize = 0;
        for (int i = 0; i < oldExcelFields.size(); i++) {
            String oldFileValue = oldExcelFields.get(i).get(ExcelFieldEnum.FILED_VALUE);
            String newFileValue = newExcelFields.get(i).get(ExcelFieldEnum.FILED_VALUE);
            if (StringUtils.isNotBlank(oldFileValue) || StringUtils.isNotBlank(newFileValue)) {
                if (!StringUtils.equals(oldFileValue, newFileValue)) {
                    changeDetail.append(oldExcelFields.get(i).get(ExcelFieldEnum.EXCEL_ANNOTATION_NAME))
                            .append("从“").append(oldFileValue).append("”修改为“").append(newFileValue).append("”；");
                    changeSize++;
                }
            }
        }
        if (changeSize == 0) {
            throw new com.ruoyi.common.exception.ServiceException("数据未修改，无法变更");
        }
        changeLog.setChangeSituationStatus(changeDetail.toString()); //变更情况

        // 操作人信息
        String revisedPeople = newJiaju.getRevisedPeople();
        revisedPeople = StringUtils.isNotBlank(revisedPeople) ? revisedPeople : SecurityUtils.getUsername();
        changeLog.setChangeSituationPerson(revisedPeople);//变更人

        // 时间信息
        String revisedTm = newJiaju.getRevisedTm();
        revisedTm = StringUtils.isNotBlank(revisedTm) ? revisedTm : new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date());
        changeLog.setChangeSituationTm(revisedTm); //变更时间

        // 变更事由
        String revisedReason = newJiaju.getRevisedReason();
        changeLog.setChangeSituationResason(StringUtils.isNotBlank(revisedReason) ? revisedReason : ""); //变更事由

        // 操作类型标记
        changeLog.setBackupFields2(updateType); //变更类型
        changeLog.setBackupFields3("家具资产");
        changeLog.setBackupFields4(newJiaju.getStorageLocation());//存放地
        changeLog.setBackupFields5(newJiaju.getKeeper());//保管人
        changeLog.setBackupFields6(newJiaju.getUsers());//使用人
        changeLog.setBackupFields7(newJiaju.getResponser());//责任人
        changeLog.setBackupFields8(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
        changeLog.setBackupFields9(newJiaju.getBackupFields9());
        propertyChangeMapper.insertPropertyChange(changeLog);
    }
    private SysUser getLoginSysUser() {
        LoginUser loginUser = SecurityUtils.getLoginUser();
        if (loginUser == null) {
            throw new RuntimeException("请先登录");
        }
        SysUser user = loginUser.getUser();
        if (user == null) {
            throw new RuntimeException("当前用户信息为空");
        }
        return user;
    }
}